// 链接服务相关
import scp2 from 'scp2';
import { Client } from 'ssh2';
// 控制台打印相关
import ora from 'ora';
import chalk from 'chalk';
// 生成log文件所需依赖
import os from 'os';
import fs from 'fs';

const env = process.argv[2] || 'dev';
const envLabel = {
  prod: '生产',
  test: '测试',
  dev: '开发',
};
// 账号
const accet = {
  username: '',
  password: '',
};
// 服务配置
const serverMap = {
  // 服务器ip&端口配置
  prod: {
    host: '',
    port: '22',
  },
  test: {
    host: '',
    port: '22',
  },
  dev: {
    host: '',
    port: '22',
  },
};
// 路径禁止为 / 或者 /*
const projectName = '';
const packagePath = `/opt/app/static/${projectName}`; // 项目部署的服务器目标位置
const dist = './dist/'; // 打包后项目文件

const conn = new Client();
const execCmd = (cmd) => {
  if (cmd) {
    return new Promise((resolve, reject) => {
      conn?.exec(cmd, (err, stream) => {
        if (err) reject(err);
        stream.on('close', (event) => resolve(event)).on('data', (_) => 0);
      });
    });
  } else {
    throw '指令为空😂';
  }
};
const execBackupCmd = async () => {
  await execCmd(`rm -rf .${packagePath}.back`); // 移除旧备份
  await execCmd(`mv ${packagePath} .${packagePath}.back`); // 将当前资源转为备份
};

const uploadTips = ora(chalk.green(`正在部署到${envLabel[env]}环境🌈`));

const fetchIp = () => {
  const ip = [];
  try {
    const networkInterfaces = os.networkInterfaces();
    for (const key in networkInterfaces) {
      networkInterfaces[key]?.forEach(({ family, address, internal, mac }) => {
        family === 'IPv4' &&
          address !== '127.0.0.1' &&
          !internal &&
          ip.push({ address, mac });
      });
    }
  } catch (e) {
    console.log(chalk.red('获取本地ip信息失败了🐞'));
    console.log(chalk.red(e));
  }
  return JSON.stringify(ip);
};

// 定义格式化封装函数
function formaData(timer) {
  const year = timer.getFullYear();
  const month = timer.getMonth() + 1; // 由于月份从0开始，因此需加1
  const day = timer.getDate();
  const hour = timer.getHours();
  const minute = timer.getMinutes();
  const second = timer.getSeconds();
  return `${pad(year, 4)}-${pad(month)}-${pad(day)} ${pad(hour)}:${pad(
    minute,
  )}:${pad(second)}`;
}

// 定义具体处理标准
// timeEl 传递过来具体的数值：年月日时分秒
// total 字符串总长度 默认值为2
// str 补充元素 默认值为"0"
function pad(timeEl, total = 2, str = '0') {
  return timeEl.toString().padStart(total, str);
}

fs.stat(dist, (err, stats) => {
  if (!err && stats.isDirectory()) {
    let time = new Date();
    fs.writeFile(
      `${dist}log`,
      `hostname: ${os.hostname()}\r\nplatform: ${os.platform()}\r\nip: ${fetchIp()}\r\ndate: ${formaData(
        time,
      )}`,
      'utf8',
      (_) => 0,
    );
  }
});

conn
  .on('ready', async () => {
    uploadTips.start();
    try {
      await execBackupCmd();
      scp2.scp(
        dist,
        {
          ...serverMap[env],
          ...accet,
          path: packagePath,
        },
        (err) => {
          uploadTips.stop();
          if (err) {
            console.log(chalk.red('项目部署出错了🐞'));
            console.log(chalk.red(err));
          } else {
            console.log(
              chalk.green(`🎉🎉🎉项目已部署到${envLabel[env]}环境😘💕☕☕☕`),
            );
          }
        },
      );
      conn.end();
    } catch (e) {
      console.log(chalk.red('备份操作出错了🐞'));
      console.log(e);
      uploadTips.stop();
    }
  })
  .connect({
    ...serverMap[env],
    ...accet,
  });
